#include <iostream>
#include <string>

using std::cout;
using std::endl;
using std::string;

template<typename T=int, size_t sz=10>
class Stack{
public:
    Stack();
    ~Stack();
    bool empty() const;
    bool full() const;
    void push(const T &value);
    void pop();
    T top();
private:
    int _top;
    T *_pdata;
};

//template<typename T = double, size_t sz>  //报错
//template<typename T = int ,size_t sz = 10>  //报错
template<typename T,size_t sz>
Stack<T,sz>::Stack()
: _top(-1)
, _pdata(new T[sz]())
//在堆上分配了一个包含sz个T类型元素的数组，并使用默认值进行初始化
//所以在这里才能看出_pdata是指向T类型数组的指针，后面可以用下标进行数组访问
{
    cout<<"Stack()"<<endl;
}

template<typename T,size_t sz>
Stack<T,sz>::~Stack(){
    cout<<"~Stack()"<<endl;
    if(_pdata){
        delete [] _pdata;
        _pdata=nullptr;
    }
}

template<typename T,size_t sz>
bool Stack<T,sz>::empty() const {
    return (-1==_top);
}

template<typename T,size_t sz>
bool Stack<T,sz>::full() const{
    return (_top == sz-1);
}

template<typename T,size_t sz>
void Stack<T,sz>::push(const T &value){
    if(!full()){
        _pdata[++_top]=value;
    }
    else{
        cout<<"栈已满，no push"<<endl;
        return;
    }
}

template<typename T,size_t sz>
void Stack<T,sz>::pop(){
    if(!empty()){
        --_top;
    }
    else{
        cout<<"栈已空，no pop"<<endl;
        return;
    }
}

template<typename T,size_t sz>
T Stack<T,sz>::top(){
    return _pdata[_top];
}

void test(){
    Stack<int,20> st;
    cout<<st.empty()<<endl;
    st.push(1);
    cout<<st.full()<<endl;

    for(size_t idx=2; idx!=12; ++idx){
        st.push(idx);
    }
    cout<<"栈满了吗？"<<st.full()<<endl;
    while(!st.empty()){
        cout<<st.top()<<" ";
        st.pop();
    }

    cout<<endl;
    cout<<"栈空了吗？"<<st.empty()<<endl;
}

void test2(){
    Stack<string,13> st;
    cout<<st.empty()<<endl;
    st.push(string("aa"));
    cout<<st.full()<<endl;

    for(size_t idx=1; idx!=15; ++idx){
        st.push(string(2,'a'+idx));     //这是string的一个构造函数，2是叠词
    }
    cout<<"栈满了吗？"<<st.full()<<endl;
    while(!st.empty()){
        cout<<st.top()<<" ";
        st.pop();
    }

    cout<<endl;
    cout<<"栈空了吗？"<<st.empty()<<endl;
}

int main()
{   
    test2();
    return 0;
}

